package me.huanmeng.heater.main;

import cn.hutool.core.io.FileUtil;
import com.ericrabil.yamlconfiguration.configuration.file.YamlConfiguration;
import lombok.Getter;
import lombok.Setter;
import lombok.SneakyThrows;
import me.huanmeng.heater.bot.Bot;
import me.huanmeng.heater.console.BotConsole;
import me.huanmeng.heater.heather.ServerImpl;
import me.huanmeng.heater.http.KaiheilaApi;
import me.huanmeng.heater.impl.BotSocketMain;
import me.huanmeng.heater.listener.SignallingListener;
import me.huanmeng.heater.plugin.Plugin;
import me.huanmeng.heater.plugin.PluginManager;
import me.huanmeng.heater.runnable.SignallingHandleRunnable;
import me.huanmeng.heater.sender.manager.ChannelManager;

import java.io.File;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Logger;

/**
 * 2021/9/26<br>
 * Heater<br>
 *
 * @author huanmeng_qwq
 */
public class HeaterMain {
    @Setter
    @Getter
    private boolean running;
    @Getter
    private static HeaterMain instance;
    @Getter
    private Bot bot;
    private BotConsole botConsole;
    @Getter
    private KaiheilaApi kaiheilaApi;
    private final ReentrantLock shutdownLock = new ReentrantLock();
    public File configFile;
    public YamlConfiguration config;
    private PluginManager pluginManager;
    @Getter
    private SignallingHandleRunnable signHandler;
    @SneakyThrows
    public HeaterMain() {
        running = true;
        configFile = new File("config.yml");
        instance=this;
        loadConfig();
        new ServerImpl();
    }

    public Logger getLogger() {
        return botConsole == null ? null : botConsole.getLogger();
    }

    public void start() throws Exception {
        botConsole = new BotConsole();
        pluginManager = new PluginManager(bot);
        final List<Plugin> plugins = pluginManager.loadPlugins(new File("plugins"));
        this.signHandler=new SignallingHandleRunnable();
        this.signHandler.start();
        this.bot = new BotSocketMain(kaiheilaApi);
        this.bot.login();
        plugins.forEach(pluginManager::enablePlugin);
        new SignallingListener();
        botConsole.start();
    }

    public boolean isDebug() {
        return config != null && config.getBoolean("debug", false);
    }

    @SneakyThrows
    public void loadConfig() {
        if (!configFile.exists()) {
            FileUtil.touch(configFile);
            FileUtil.writeFromStream(getClass().getClassLoader().getResourceAsStream("config.yml"), configFile);
        }
        config = YamlConfiguration.loadConfiguration(configFile);
        kaiheilaApi = new KaiheilaApi(config.getString("token"));
    }

    public static void main(String[] args) throws Exception {
        new HeaterMain().start();
    }

    public void stop() {
        new Thread("Stop Thread") {
            @Override
            public void run() {
                stopBot();
            }
        }.start();
    }

    private void stopBot() {
        shutdownLock.lock();
        if (!running) {
            shutdownLock.unlock();
            return;
        }
        final List<Plugin> plugins = pluginManager.getPlugins();
        for (Plugin plugin : plugins) {
            pluginManager.disablePlugin(plugin);
        }
        bot.logout();
        running = false;
        shutdownLock.unlock();
        //等待socket完全关闭
        new Thread(() -> {
            try {
                Thread.sleep(500);
                System.exit(0);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }).start();
    }
}
